package My

import (
	"db2s/ETL"
	"db2s/global"
	"fmt"
	"strings"
	//"vitess.io/vitess/go/vt/sqlparser"
)

func (my TableInfoMeta) ViewName(s global.TablesMetaInfoInput) (result global.ObjectNameReturnResult, err error) {
	var f1 any
	var event = "[MySQLViewName]"
	result.BaseResult.Sql = fmt.Sprintf("select TABLE_NAME from information_schema.views where TABLE_SCHEMA ='%v' %v",
		s.TableInfo.Schema, func() string {
			switch {
			case s.TableInfo.Table == "*":
				return ""
			case strings.Contains(s.TableInfo.Table, "%"):
				return fmt.Sprintf(" and TABLE_NAME like '%%%v%%'", s.TableInfo.Table)
			default:
				return fmt.Sprintf(" and TABLE_NAME = '%v'", s.TableInfo.Table)
			}
		}())
	if result.BaseResult.TimeOut, f1, err = ExecSelectSql(ExecSqlInputS{
		Ss:           s,
		Event:        event,
		SelectSqlStr: result.BaseResult.Sql,
		Expect:       ETL.StringGarth,
	}); err != nil || f1 == nil || len(f1.([]string)) == 0 {
		return
	}
	result.Result = f1.([]string)
	return
}

func (my TableInfoMeta) ViewExist(s global.TablesMetaInfoInput) (result global.ObjectExistReturnResult, err error) {
	var f1 any
	var event = "[MySQLViewExist]"
	result.BaseResult.Sql = fmt.Sprintf("select count(1) as `sum` from information_schema.views where  TABLE_SCHEMA ='%v'  and TABLE_NAME = '%v'", s.TableInfo.Schema, s.TableInfo.Table)
	if result.BaseResult.TimeOut, f1, err = ExecSelectSql(ExecSqlInputS{
		Ss:           s,
		Event:        event,
		SelectSqlStr: result.BaseResult.Sql,
		Expect:       ETL.Map,
	}); err != nil || f1 == nil || len(f1.(map[string]any)) == 0 {
		return
	}
	if fmt.Sprintf("%v", f1.(map[string]any)["sum"]) == "1" {
		result.Result = true
	}
	return
}
func (my SchemaObjectMeta) viewColumn(s global.SchemaObjectInput) (result []string, err error) {
	var f1 any
	var event = "[MySQLViewColumn]"
	sqlStr := fmt.Sprintf("select COLUMN_NAME from information_schema.columns where table_schema='%v' and table_name='%v' order by ORDINAL_POSITION;", s.Schema, s.Table)
	if _, f1, err = ExecSelectSql(ExecSqlInputS{
		Ss:           s,
		Event:        event,
		SelectSqlStr: sqlStr,
		Expect:       ETL.StringGarth,
	}); err != nil || f1 == nil || len(f1.([]string)) == 0 {
		return
	}
	result = f1.([]string)
	return
}
func viewConvert(d global.ViewResultDefinition) (Convert global.ViewDefinitionConvertS) {
	return global.ViewDefinitionConvertS{
		Schema:       d.Schema,
		Name:         d.Name,
		Column:       d.Column,
		Definer:      d.Definer,
		SecurityType: d.SecurityType,
		BodyText:     d.BodyText,
		PrintInfo:    d.PrintInfo,
	}
}
func viewPrintInfo(x global.ViewResultDefinition) (res string) {
	return fmt.Sprintf(""+
		"CREATE \n"+
		"OR REPLACE \n"+
		"%v \n"+
		"%v \n"+
		"%v \n"+
		"VIEW `%v`.`%v` %v \n"+
		"AS \n"+
		"%v ;",
		AlgorithmGeneral(""),
		definerGeneral(x.Definer),
		sqlSecurity(x.SecurityType),
		x.Schema, x.Name, viewColumnGeneral(x.Column),
		x.BodyText,
	)
}
func (my SchemaObjectMeta) View(s global.SchemaObjectInput) (result global.SchemaObjectReturnResult, err error) {
	var (
		f1    any
		x     global.ViewResultDefinition
		event = "[MySQLView]"
	)
	result.BaseResult.Sql = fmt.Sprintf("SELECT `TABLE_SCHEMA` as `schema`,TABLE_NAME as `viewName`,`DEFINER` as `definer`,SECURITY_TYPE AS `securityType`,`VIEW_DEFINITION` as `bodyText` \n"+
		"FROM `INFORMATION_SCHEMA`.`VIEWS` \n"+
		"where 1=1 and TABLE_SCHEMA = '%v' and TABLE_NAME = '%v'", s.Schema, s.Table)
	if result.BaseResult.TimeOut, f1, err = ExecSelectSql(ExecSqlInputS{
		Ss:           s,
		Event:        event,
		SelectSqlStr: result.BaseResult.Sql,
		Expect:       ETL.Map,
	}); err != nil || f1 == nil || len(f1.(map[string]any)) == 0 {
		return
	}
	if err = global.MapSubToStructSubJsonName(f1.(map[string]any), &x); err != nil {
		return
	}
	x.Type = "view"
	if x.Column, err = my.viewColumn(s); err != nil {
		return
	}
	x.PrintInfo = viewPrintInfo(x)
	result.ViewResult.Definition = x
	result.ViewResult.Convert = viewConvert(x)
	return
}

//	func gbkToUtf8Str(gbk string) (utf8Str string) {
//		// 假设这是一个 GBK 编码的字符串
//		gbkStr := []byte{} // 这里填入 GBK 编码的字节数据
//
//		// 创建转换器
//		decoder := simplifiedchinese.GBK.NewDecoder()
//
//		// 转换为 UTF-8
//		utf8Str, err := ioutil.ReadAll(transform.NewReader(strings.NewReader(string(gbkStr)), decoder))
//		if err != nil {
//			fmt.Println("Error converting string:", err)
//			return
//		}
//
//		fmt.Println("Converted UTF-8 string:", string(utf8Str))
//	}
func viewDefinitionParse(sql string) (err error) {
	sql1 := strings.ReplaceAll(sql, "\"", "")
	fmt.Println("-----jjj:", sql1)
	//var parser *sqlparser.Parser
	//if parser, err = sqlparser.New(sqlparser.Options{
	//	MySQLServerVersion: "8.0.32",
	//}); err != nil {
	//	return
	//}
	//stmt, err := parser.Parse(sql1)
	//if err != nil {
	//	fmt.Printf("Error parsing SQL: %v\n", err)
	//	return
	//}
	//// 打印解析结果
	//fmt.Println("Parsed Statement:")
	//fmt.Println(stmt)
	// 遍历语法树
	//sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool) {
	//	switch n := node.(type) {
	//	case *sqlparser.Select:
	//		fmt.Println("Found a SELECT statement")
	//		for _, col := range n.SelectExprs {
	//			fmt.Printf("Column: %v\n", sqlparser.String(col))
	//		}
	//	case *sqlparser.TableExpr:
	//		fmt.Printf("Table: %v\n", sqlparser.String(n))
	//	case *sqlparser.Where:
	//		fmt.Printf("Where clause: %v\n", sqlparser.String(n))
	//	}
	//	return true
	//}, stmt)
	return
}

// 处理--注释中包含分号，进行分号识别
func commentActive(s string) (res string) {
	res = s
	if strings.Contains(s, "--") {
		res = strings.ReplaceAll(res, "--", "-- ")
	}
	return
}

func keywordsActive(keywords []string, s string) (res string) {
	var result []string
	for _, v := range strings.Split(s, " ") {
		p := fmt.Sprintf("%v", v)
		for _, q := range keywords {
			if strings.EqualFold(v, q) {
				p = fmt.Sprintf("`%v`", v)
				break
			}
		}
		result = append(result, p)
	}
	res = strings.Join(result, " ")
	return
}
func viewDefinitionNotSupportActive(s string) (res string) {
	var rr []string
	var keywords = getMySqlKeywords()
	for _, v := range strings.Split(s, "\n") {
		rr = append(rr, commentActive(v))
		rr = append(rr, keywordsActive(keywords, v))
	}
	res = strings.Join(rr, "\n")
	return
}
func AlgorithmGeneral(s string) (res string) {
	if len(s) > 0 {
		//ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}
		res = fmt.Sprintf("ALGORITHM = %v ", s)
	}
	return
}
func definerGeneral(s string) (res string) {
	if len(s) > 0 {
		res = fmt.Sprintf(" DEFINER=`%v` ", strings.Join(strings.Split(s, "@"), "`@`"))
	}
	return
}
func sqlSecurity(s string) (res string) {
	if len(s) > 0 {
		//SQL SECURITY { DEFINER | INVOKER }
		res = fmt.Sprintf(" SQL SECURITY %v ", s)
	}
	return
}
func viewColumnGeneral(s []string) (res string) {
	if len(s) > 0 {
		res = fmt.Sprintf("(`%v`)", strings.Join(s, "`,`"))
	}
	return
}
func createView(s global.SchemaObjectInput) (res global.ObjectFixSqlS, err error) {
	res.CreateSql = append(res.CreateSql, fmt.Sprintf(""+
		"CREATE \n"+
		"OR REPLACE \n"+
		"%v \n"+
		"%v \n"+
		"%v \n"+
		"VIEW `%v`.`%v` %v \n"+
		"AS \n"+
		"%v ;",
		AlgorithmGeneral(""),
		definerGeneral(s.ObjectDefinition.ViewResult.Convert.Definer),
		sqlSecurity(s.ObjectDefinition.ViewResult.Convert.SecurityType),
		s.Schema, s.ObjectDefinition.ViewResult.Convert.Name, viewColumnGeneral(s.ObjectDefinition.ViewResult.Convert.Column),
		s.ObjectDefinition.ViewResult.Convert.BodyText,
	))
	return
}
